home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / oath.lha / oath / src / minString.cc < prev    next >
C/C++ Source or Header  |  1991-08-29  |  54KB  |  2,281 lines

  1. //***************************************************************************/
  2. //             OATH :: Object-oriented Abstract Type Hierarchy
  3. //***************************************************************************/
  4. //
  5. //  Copyright (C) 1991, 1990  Texas Instruments Incorporated
  6. //  Permission is granted to any individual or institution
  7. //  to use, copy, modify, and distribute this software,
  8. //  provided that this complete copyright and permission notice
  9. //  is maintained, intact, in all copies and supporting documentation.
  10. //
  11. //  Texas Instruments Incorporated provides this software "as is"
  12. //  without express or implied warranty.
  13. //
  14. //***************************************************************************
  15. //  minString (minStringA, minStringG, dlMinStringG, pMinStringG)
  16. //  minStringPos (minStringPosA, minStringPosG, dlMinStringPosG, pMinStringPosG)
  17. //
  18. //  History:
  19. //    07/91  Brian M Kennedy  import, export, typeRegister
  20. //    06/91  Brian M Kennedy  New macros & format; remove printDiagnostic
  21. //    10/90  Brian M Kennedy  Major Rewrite
  22. //    02/90  Brian M Kennedy  Original
  23. //
  24. //***************************************************************************/
  25.  
  26. #include "copyright.h"
  27.  
  28. #include <oath/minString.h>
  29.  
  30. #include <stdlib.h>
  31.  
  32. #include <math.h>      /* included because abs() not in stdlib */
  33.  
  34. #include <iostream.h>
  35.  
  36. /////////////////////////////////////////////////////////////////////////////
  37. // minString Outlines
  38.  
  39. OUTLINES(minString, string)
  40.  
  41. /////////////////////////////////////////////////////////////////////////////
  42. // dlMinStringG Outlines
  43.  
  44. OUTLINES_G(dlMinString, minString)
  45.  
  46. // Constructors //////////
  47.  
  48.     dlMinStringG::
  49. dlMinStringG (int IsConst)
  50.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  51.    {ref();
  52.        {End = Header = new dlcNodeP;}
  53.     deref();
  54.    }
  55.  
  56.     dlMinStringG::
  57. dlMinStringG (const seqG* S, int IsConst)
  58.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  59.    {ref();
  60.        {End = Header = new dlcNodeP;
  61.         for(posA P = S->makePos(0, 0); P(); ++P)
  62.        {characterA C = characterA::isa(*P);
  63.         if(!!C)
  64.             End = End->insertAfter(C.guts());
  65.        }
  66.        }
  67.     deref();
  68.    }
  69.  
  70.     dlMinStringG::
  71. dlMinStringG (const posG* Start, const posG* Beyond, int IsConst)
  72.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  73.    {ref();
  74.        {End = Header = new dlcNodeP;
  75.     if(!Beyond)
  76.        {for(posA P = (posA&)Start->makeCopy(0); P(); ++P)
  77.            {characterA C = characterA::isa(*P);
  78.             if(!!C)
  79.                 End = End->insertAfter(C.guts());
  80.            }
  81.        }
  82.     else
  83.        {ensure(Start->parent()->is(Beyond->parent()), 
  84.            "The two Pos's are not from the same Seq!");
  85.         for(posA P = (posA&)Start->makeCopy(0); 
  86.                                       !Beyond->isEqual(P.guts()); ++P)
  87.            {assumed(P(), "Second Pos is not after the first!");
  88.             characterA C = characterA::isa(*P);
  89.             if(!!C)
  90.                 End = End->insertAfter(C.guts());
  91.            }
  92.        }
  93.        }
  94.     deref();
  95.    }
  96.  
  97.     dlMinStringG::
  98. dlMinStringG (const char* S, int IsConst)
  99.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  100.    {ref();
  101.        {End = Header = new dlcNodeP;
  102.     for(const char* P = S; *P; ++P)
  103.        {characterA C = characterA::make(*P);
  104.         End = End->insertAfter(C.guts());
  105.        }
  106.        }
  107.     deref();
  108.    }
  109.  
  110.     dlMinStringG::
  111. dlMinStringG (const char* Start, const char* Beyond, int IsConst)
  112.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  113.    {ref();
  114.        {End = Header = new dlcNodeP;
  115.     if(!Beyond)
  116.        {for(const char* P = Start; *P; ++P)
  117.            {characterA C = characterA::make(*P);
  118.             End = End->insertAfter(C.guts());
  119.            }
  120.        }
  121.     else
  122.        {ensure(Beyond > Start, "Second Ptr is not after the first!");
  123.         for(const char* P = Start; (Beyond != P); ++P)
  124.            {characterA C = characterA::make(*P);
  125.             End = End->insertAfter(C.guts());
  126.            }
  127.        }
  128.        }
  129.     deref();
  130.    }
  131.  
  132.     dlMinStringG::
  133. dlMinStringG (int Uppercase, const seqG* S, int IsConst)
  134.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  135.    {ref();
  136.        {End = Header = new dlcNodeP;
  137.     for(posA P = S->makePos(0, 0); P(); ++P)
  138.        {characterA C = characterA::isa(*P);
  139.         if(!!C)
  140.             End = End->insertAfter(Uppercase ? C.guts()->uppercase()
  141.                          : C.guts()->lowercase());
  142.        }
  143.        }
  144.     deref();
  145.    }
  146.  
  147.     dlMinStringG::
  148. dlMinStringG (int Uppercase, const posG* Start, const posG* Beyond,
  149.           int IsConst)
  150.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  151.    {ref();
  152.        {End = Header = new dlcNodeP;
  153.     if(!Beyond)
  154.        {for(posA P = (posA&)Start->makeCopy(0); P(); ++P)
  155.            {characterA C = characterA::isa(*P);
  156.             if(!!C)
  157.                 End = End->insertAfter(Uppercase ? C.guts()->uppercase()
  158.                              : C.guts()->lowercase());
  159.            }
  160.        }
  161.     else
  162.        {ensure(Start->parent()->is(Beyond->parent()), 
  163.            "The two Pos's are not from the same Seq!");
  164.         for(posA P = (posA&)Start->makeCopy(0);
  165.                                  !Beyond->isEqual(P.guts()); ++P)
  166.            {assumed(P(), "Second Pos is not after the first!");
  167.             characterA C = characterA::isa(*P);
  168.             if(!!C)
  169.                 End = End->insertAfter(Uppercase ? C.guts()->uppercase()
  170.                              : C.guts()->lowercase());
  171.            }
  172.        }
  173.        }
  174.     deref();
  175.    }
  176.  
  177.     dlMinStringG::
  178. dlMinStringG (int Uppercase, const char* S, int IsConst)
  179.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  180.    {ref();
  181.        {End = Header = new dlcNodeP;
  182.     for(const char* P = S; *P; ++P)
  183.        {characterA C = characterA::make(*P);
  184.         End = End->insertAfter(Uppercase ? C.guts()->uppercase() 
  185.                          : C.guts()->lowercase());
  186.        }
  187.        }
  188.     deref();
  189.    }
  190.  
  191.     dlMinStringG::
  192. dlMinStringG (int Uppercase, const char* Start, const char* Beyond, int IsConst)
  193.    :minStringG(IsConst), Header(0), End(0), PosList(0)
  194.    {ref();
  195.        {End = Header = new dlcNodeP;
  196.     if(!Beyond)
  197.        {for(const char* P = Start; *P; ++P)
  198.            {characterA C = characterA::make(*P);
  199.             End = End->insertAfter(Uppercase ? C.guts()->uppercase()
  200.                          : C.guts()->lowercase());
  201.            }
  202.        }
  203.     else
  204.        {ensure(Beyond > Start, "Second Ptr is not after the first!");
  205.         for(const char* P = Start; (Beyond != P); ++P)
  206.            {characterA C = characterA::make(*P);
  207.             End = End->insertAfter(Uppercase ? C.guts()->uppercase()
  208.                          : C.guts()->lowercase());
  209.            }
  210.        }
  211.        }
  212.     deref();
  213.    }
  214.  
  215.     dlMinStringG::
  216. ~dlMinStringG ()
  217.    {ref();
  218.        {while(Header->next())
  219.         Header->deleteNext();
  220.     delete Header;
  221.        }
  222.     deref();
  223.    }
  224.  
  225.  
  226. // oathCore Operations //////////
  227.  
  228.     void dlMinStringG::
  229. export (exportP& X) const
  230.    {X.writeType(TypeName);
  231.     int Count = count();
  232.     X.stream() << Count << ' ';
  233.     if(Count)
  234.         dlMinStringG::ostreamInsertion(X.stream());
  235.    }
  236.  
  237.     objA dlMinStringG::
  238. import (importP& M)
  239.    {int Count;
  240.     M.stream() >> Count;
  241.     M.stream().get();
  242.     if(Count)
  243.        {dlcNodeP * Header = new dlcNodeP;
  244.         dlcNodeP * End = Header;
  245.     for(int I = 0; I < Count; ++I)
  246.            {characterA Tmp = characterA::make(M.stream().get());
  247.         End->Next = new dlcNodeP (End, 0, Tmp.guts());
  248.         End = End->Next;
  249.            }
  250.     return new dlMinStringG (Header, End);
  251.        }
  252.     else
  253.         return new dlMinStringG ();
  254.    }
  255.  
  256.  
  257. // obj Operations //////////
  258.  
  259.     int dlMinStringG::
  260. isEqual (const objG* O) const
  261.    {if(is(O))
  262.     return TRUE;
  263.     if(!O->isType(stringG::Type))
  264.         return FALSE;
  265.     const stringG* S = (const stringG*)O;
  266.     posA Pthis = makePos(0, 0);
  267.     posA PS    = S->makePos(0, 0);
  268.     while(Pthis())
  269.        {if(PS.isPastEnd())
  270.         return FALSE;
  271.     if(!(*Pthis).is(*PS))
  272.         return FALSE;
  273.     ++Pthis;
  274.     ++PS;
  275.        }
  276.     return (PS.isPastEnd() ? TRUE : FALSE);
  277.    }
  278.  
  279.     objA dlMinStringG::
  280. makeCopy (int MakeConst) const
  281.    {if(MakeConst)
  282.         return new pMinStringG (this);
  283.     else
  284.        {dlcNodeP * NewHead = new dlcNodeP;
  285.         dlcNodeP * NewEnd  = NewHead;
  286.     for(dlcNodeP * P = Header; P->next(); P = P->next())
  287.         NewEnd = NewEnd->insertAfter(P->nextObj().guts());
  288.     return new dlMinStringG (NewHead, NewEnd);
  289.        }
  290.    }
  291.  
  292. // bag Operations //////////
  293.  
  294.     int dlMinStringG::
  295. isEmpty () const
  296.    {return !Header->next();}
  297.  
  298.     int dlMinStringG::
  299. count () const
  300.    {int C = 0;
  301.     for(dlcNodeP *N = Header->next(); N; N = N->next())
  302.     C++;
  303.     return C;
  304.    }
  305.  
  306.     int dlMinStringG::
  307. contains (const objG* O) const
  308.    {if(!O->isImplementedAs(characterG::Type))
  309.         return FALSE;
  310.     for(dlcNodeP *N = Header->next(); N; N = N->next())
  311.     if(O->is(N->thisObj().guts()))
  312.         return TRUE;
  313.     return FALSE;
  314.    }
  315.  
  316.     int dlMinStringG::
  317. containsEqual (const objG* O) const
  318.    {if(!O->isImplementedAs(characterG::Type))
  319.         return FALSE;
  320.     for(dlcNodeP *N = Header->next(); N; N = N->next())
  321.     if(O->is(N->thisObj().guts()))
  322.         return TRUE;
  323.     return FALSE;
  324.    }
  325.  
  326.     int dlMinStringG::
  327. canContain (const objG* O) const
  328.    {return O->isImplementedAs(characterG::Type);}
  329.  
  330.     void dlMinStringG::
  331. insert (const objG* O)
  332.    {if(O->isImplementedAs(characterG::Type))
  333.         End = End->insertAfter((characterG*)O);
  334.    }
  335.  
  336.     void dlMinStringG::
  337. append (const bagG* B)
  338.    {B->applyX(callSelf, this);}
  339.  
  340.     void dlMinStringG::
  341. apply (void (*F)(objA)) const
  342.    {for(dlcNodeP *N = Header->next(); N; N = N->next())
  343.     F(N->thisObj());
  344.    }
  345.  
  346.     bagG* dlMinStringG::
  347. applyX (objA (*F)(objA), bagG* B) const
  348.    {for(dlcNodeP *N = Header->next(); N; N = N->next())
  349.        {objA O = F(N->thisObj());
  350.         B->insert(O.guts());
  351.        }
  352.     return B;
  353.    }
  354.  
  355.     bagG* dlMinStringG::
  356. applyX (bagA (*F)(objA), bagG* B) const
  357.    {for(dlcNodeP *N = Header->next(); N; N = N->next())
  358.        {bagA O = F(N->thisObj());
  359.         B->append(O.guts());
  360.        }
  361.     return B;
  362.    }
  363.  
  364. // queue Operations //////////
  365.  
  366.     const objG* dlMinStringG::
  367. remove ()
  368.    {assumed(!isEmpty(), "operator>>() attempted on an empty Queue!");
  369.     adjustPosList(Header->next(), Header);
  370.     const objG* O = Header->nextObj().guts();
  371.     if(End == Header->next())
  372.     End = Header;
  373.     Header->deleteNext();
  374.     return O;
  375.    }
  376.  
  377.  
  378. // seq Operations //////////
  379.  
  380.     const objG* dlMinStringG::
  381. subscript (int I) const
  382.    {dlcNodeP* N = internalPosition(I);
  383.     assumed(N->next(), "Indexed beyond end of Seq!");
  384.     return N->nextObj().guts();
  385.    }
  386.  
  387.     const objG* dlMinStringG::
  388. subscript (const posG* P) const
  389.    {ensure(!P->isNil() && is(P->parent()), "Position not from this seq!");
  390.     return ((dlMinStringPosG*)P)->Prev->nextObj().guts();
  391.    }
  392.  
  393.     seqA dlMinStringG::
  394. makeSeq (const posG* Start, const posG* Beyond, int MakeConst) const
  395.    {return MakeConst ? (seqG*)new pMinStringG (Start, Beyond)
  396.              : (seqG*)new dlMinStringG (Start, Beyond);}
  397.  
  398.     seqA dlMinStringG::
  399. makeSeq (int Start, int Beyond, int MakeConst) const
  400.    {posA S = makePos(Start, TRUE);
  401.     posA B = makePos(Beyond, TRUE);
  402.     return MakeConst ? (seqG*)new pMinStringG  (S.guts(), B.guts())
  403.              : (seqG*)new dlMinStringG (S.guts(), B.guts());
  404.    }
  405.  
  406.  
  407. // fifoQueue Operations //////////
  408.  
  409.  
  410. // deq Operations //////////
  411.  
  412.     void dlMinStringG::
  413. pushFront (const objG* O)
  414.    {if(O->isImplementedAs(characterG::Type))
  415.        {Header->insertAfter((characterG*)O);
  416.         if(Header == End)
  417.         End = Header->next();
  418.        }
  419.    }
  420.  
  421.     const objG* dlMinStringG::
  422. pullEnd ()
  423.    {assumed(!isEmpty(), "pullEndX() attempted on an empty Queue!");
  424.     adjustPosList(End, End->prev());
  425.     const objG* O = End->thisObj().guts();
  426.     End = End->prev();
  427.     End->deleteNext();
  428.     return O;
  429.    }
  430.  
  431.  
  432. // list Operations //////////
  433.  
  434.     void dlMinStringG::
  435. insertList (const listPosG* P, const objG* O)
  436.    {ensure(!P->isNil() && is(P->parent()), "Position not from this seq!");
  437.     if(O->isImplementedAs(characterG::Type))
  438.        {((dlMinStringPosG*)P)->Prev->insertAfter((characterG*)O);
  439.         if(((dlMinStringPosG*)P)->Prev == End)
  440.         End = End->next();
  441.        }
  442.    }
  443.  
  444.  
  445.     const objG* dlMinStringG::
  446. removeList (const listPosG* P)
  447.    {ensure(!P->isNil() && is(P->parent()), "Position not from this seq!");
  448.     dlcNodeP* N = ((dlMinStringPosG*)P)->Prev->next();
  449.     assumed(N, "Attempt to delete past end with dlMinStringLT::extractX(P,O)!");
  450.     adjustPosList(N, ((dlMinStringPosG*)P)->Prev);
  451.     const objG* O = ((dlMinStringPosG*)P)->Prev->nextObj().guts();
  452.     if(N == End)
  453.     End = End->prev();
  454.     ((dlMinStringPosG*)P)->Prev->deleteNext();
  455.     return O;
  456.    } 
  457.  
  458.  
  459. // string Operations //////////
  460.  
  461.     const char * dlMinStringG::
  462. charStar () const
  463.    {int Count = count();
  464.     char * S  = new char[Count + 1];
  465.     char * Stop = S;
  466.     for(dlcNodeP* P = Header; P->next(); P = P->next())
  467.        {if(*Stop = P->nextObj().value())            
  468.         Stop++;
  469.     else
  470.         break;
  471.        }
  472.     *Stop = '\0';
  473.     return S;
  474.    }
  475.  
  476.     void dlMinStringG::
  477. charStarX (char * C, int N) const
  478.    {int Count = count();
  479.     Count = ((N < Count) ? N : Count);
  480.     dlcNodeP* P = Header;
  481.     for(int I = 0; I < Count; I++)
  482.        {C[I] = P->nextObj().value();
  483.     P = P->next();
  484.        }
  485.    }
  486.  
  487.  
  488.     int dlMinStringG::
  489. hash () const    // K = 4
  490.    {int H = 0;
  491.     for(dlcNodeP *P = Header->next(); P; P = P->next())
  492.     H = (H << 2) + P->thisObj().value();
  493.     return abs(H);
  494.    }
  495.  
  496.     int dlMinStringG::
  497. hash (int K) const
  498.    {if(K == 4)
  499.         return dlMinStringG::hash();
  500.     else
  501.        {int H = 0;
  502.     for(dlcNodeP *P = Header->next(); P; P = P->next())
  503.         H = (K * H) + P->thisObj().value();
  504.     return abs(H);
  505.        }
  506.    }
  507.  
  508.     int dlMinStringG::
  509. hashLower () const    // K = 4
  510.    {int H = 0;
  511.     for(dlcNodeP *P = Header->next(); P; P = P->next())
  512.     H = (H << 2) + tolower(P->thisObj().value());
  513.     return abs(H);
  514.    }
  515.  
  516.     int dlMinStringG::
  517. hashLower (int K) const
  518.    {if(K == 4)
  519.         return dlMinStringG::hash();
  520.     else
  521.        {int H = 0;
  522.     for(dlcNodeP *P = Header->next(); P; P = P->next())
  523.         H = (K * H) + tolower(P->thisObj().value());
  524.     return abs(H);
  525.        }
  526.    }
  527.  
  528.     int dlMinStringG::
  529. hashUpper () const    // K = 4
  530.    {int H = 0;
  531.     for(dlcNodeP *P = Header->next(); P; P = P->next())
  532.     H = (H << 2) + toupper(P->thisObj().value());
  533.     return abs(H);
  534.    }
  535.  
  536.     int dlMinStringG::
  537. hashUpper (int K) const
  538.    {if(K == 4)
  539.         return dlMinStringG::hash();
  540.     else
  541.        {int H = 0;
  542.     for(dlcNodeP *P = Header->next(); P; P = P->next())
  543.         H = (K * H) + toupper(P->thisObj().value());
  544.     return abs(H);
  545.        }
  546.    }
  547.  
  548.     int dlMinStringG::
  549. isEqual (const char * PS) const
  550.    {stringPosA Pthis = (stringPosA&)makePos(0, 0);
  551.     while(Pthis())
  552.        {if(!*PS)
  553.         return FALSE;
  554.     if((*Pthis).value() != *PS)
  555.         return FALSE;
  556.     ++Pthis;
  557.     ++PS;
  558.        }
  559.     return (!*PS ? TRUE : FALSE);
  560.    }
  561.  
  562.     int dlMinStringG::
  563. isEqual (const stringPosG* Start, const stringPosG* Beyond) const
  564.    {assumed(!Start->isNil() && !Beyond->isNil()
  565.                 && Start->parent()->is(Beyond->parent()),
  566.         "The two Pos's are not from the same String!");
  567.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  568.     stringPosA PS    = (stringPosA&)Start->makeCopy(0);
  569.     stringPosA PE    = Beyond;
  570.     while(Pthis())
  571.        {if(PE == PS)
  572.         return FALSE;
  573.     if(*Pthis != *PS)
  574.         return FALSE;
  575.     ++Pthis;
  576.     ++PS;
  577.        }
  578.     return (PE == PS ? TRUE : FALSE);
  579.    }
  580.  
  581.     int dlMinStringG::
  582. isEqualAnyCase (const stringG* S) const
  583.    {if(S->isNil())
  584.     return FALSE;
  585.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  586.     stringPosA PS    = (stringPosA&)S->makePos(0, 0);
  587.     while(Pthis())
  588.        {if(PS.isPastEnd())
  589.         return FALSE;
  590.     if((*Pthis).lowercase() != (*PS).lowercase())
  591.         return FALSE;
  592.     ++Pthis;
  593.     ++PS;
  594.        }
  595.     return (PS.isPastEnd() ? TRUE : FALSE);
  596.    }
  597.  
  598.     int dlMinStringG::
  599. isEqualAnyCase (const char * PS) const
  600.    {stringPosA Pthis = (stringPosA&)makePos(0, 0);
  601.     while(Pthis())
  602.        {if(!*PS)
  603.         return FALSE;
  604.     if((*Pthis).lowercase().value() != tolower(*PS))
  605.         return FALSE;
  606.     ++Pthis;
  607.     ++PS;
  608.        }
  609.     return (!*PS ? TRUE : FALSE);
  610.    }
  611.  
  612.     int dlMinStringG::
  613. isEqualAnyCase (const stringPosG* Start, const stringPosG* Beyond) const
  614.    {assumed(!Start->isNil() && !Beyond->isNil()
  615.                 && Start->parent()->is(Beyond->parent()),
  616.         "The two Pos's are not from the same String!");
  617.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  618.     stringPosA PS    = (stringPosA&)Start->makeCopy(0);
  619.     stringPosA PE    = Beyond;
  620.     while(Pthis())
  621.        {if(PE == PS)
  622.         return FALSE;
  623.     if((*Pthis).lowercase() != (*PS).lowercase())
  624.         return FALSE;
  625.     ++Pthis;
  626.     ++PS;
  627.        }
  628.     return (PE == PS ? TRUE : FALSE);
  629.    }
  630.  
  631.     int dlMinStringG::
  632. lessThan (const stringG* S) const
  633.    {if(is(S))
  634.     return FALSE;
  635.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  636.     stringPosA PS    = (stringPosA&)S->makePos(0, 0);
  637.     while(Pthis())
  638.        {if(PS.isPastEnd())
  639.         return FALSE;
  640.     characterA Cthis = *Pthis;
  641.     characterA CS    = *PS;
  642.     if(Cthis < CS)
  643.         return TRUE;
  644.     if(Cthis > CS)
  645.         return FALSE;
  646.     ++Pthis;
  647.     ++PS;
  648.        }
  649.     return (PS.isPastEnd() ? FALSE : TRUE);
  650.    }
  651.  
  652.     int dlMinStringG::
  653. moreThan (const stringG* S) const
  654.    {if(is(S))
  655.     return FALSE;
  656.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  657.     stringPosA PS    = (stringPosA&)S->makePos(0, 0);
  658.     while(PS())
  659.        {if(Pthis.isPastEnd())
  660.         return FALSE;
  661.     characterA Cthis = *Pthis;
  662.     characterA CS    = *PS;
  663.     if(Cthis > CS)
  664.         return TRUE;
  665.     if(Cthis < CS)
  666.         return FALSE;
  667.     ++Pthis;
  668.     ++PS;
  669.        }
  670.     return (Pthis.isPastEnd() ? FALSE : TRUE);
  671.    }
  672.  
  673.     ostream& dlMinStringG::
  674. ostreamInsertion (ostream& F) const
  675.    {for(stringPosA P = (stringPosA&)makePos(0, 0); P(); ++P)
  676.     F << *P;
  677.     return F;
  678.    }
  679.  
  680.     istream& dlMinStringG::
  681. istreamExtraction (istream& F)
  682.    {char C;
  683.     while(F.get(C))
  684.         stringInsert(C);
  685.     return F;
  686.    }   
  687.  
  688.     void dlMinStringG::
  689. stringInsert (const characterG* C)
  690.    {End = End->insertAfter(C);}
  691.  
  692.     void dlMinStringG::
  693. stringInsert (char C)
  694.    {End = End->insertAfter(characterA::make(C).guts());}
  695.  
  696.     void dlMinStringG::
  697. stringAppend (const stringG* S)
  698.    {for(stringPosA P = (stringPosA&)S->makePos(0, 0); P(); ++P)
  699.         End = End->insertAfter((*P).guts());
  700.    }
  701.  
  702.     void dlMinStringG::
  703. stringAppend (const char* S)
  704.    {for(; *S; S++)
  705.         End = End->insertAfter(characterA::make(*S).guts());
  706.    }
  707.  
  708.     stringG* dlMinStringG::
  709. applyStringX (characterA (*F)(characterA), stringG* S) const
  710.    {for(dlcNodeP *N = Header->next(); N; N = N->next())
  711.        {characterA C = F(N->thisObj());
  712.         S->stringInsert(C.guts());
  713.        }
  714.     return S;
  715.    }
  716.  
  717.     stringG* dlMinStringG::
  718. applyStringX (stringA (*F)(characterA), stringG* S) const
  719.    {for(dlcNodeP *N = Header->next(); N; N = N->next())
  720.        {stringA C = F(N->thisObj());
  721.         S->stringAppend(C.guts());
  722.        }
  723.     return S;
  724.    }
  725.  
  726.     void dlMinStringG::
  727. lowercase ()
  728.    {ensure(FALSE, "Sorry, not implemented!");}
  729.  
  730.     void dlMinStringG::
  731. uppercase ()
  732.    {ensure(FALSE, "Sorry, not implemented!");}
  733.  
  734.     stringA dlMinStringG::
  735. makeLower (int MakeConst) const
  736.    {return MakeConst ? (stringG*)new pMinStringG  (FALSE, this)
  737.              : (stringG*)new dlMinStringG (FALSE, this);
  738.    }
  739.  
  740.     stringA dlMinStringG::
  741. makeUpper (int MakeConst) const
  742.    {return MakeConst ? (stringG*)new pMinStringG  (TRUE, this)
  743.              : (stringG*)new dlMinStringG (TRUE, this);
  744.    }
  745.  
  746.  
  747. // dlMinString Operations //////////
  748.  
  749.     dlcNodeP * dlMinStringG::
  750. internalPosition (int I) const
  751.    {if(!I)
  752.         return Header;
  753.     dlcNodeP* N = Header;
  754.     for(int J = 0; (J < I) && N->next(); J++)
  755.     N = N->next();
  756.     return N;
  757.    }
  758.  
  759.     void dlMinStringG::
  760. adjustPosList (dlcNodeP * CurrentPrev, dlcNodeP * NewPrev)
  761.    {dlMinStringPosG * Pos = PosList;
  762.     while(Pos)
  763.        {if(Pos->Prev == CurrentPrev)
  764.         Pos->Prev = NewPrev;
  765.     Pos = Pos->NextPos;
  766.        }
  767.    }
  768.  
  769.  
  770. /////////////////////////////////////////////////////////////////////////////
  771. // pMinStringG Outlines
  772.  
  773. OUTLINES_G(pMinString, minString)
  774.  
  775. // Constructors //////////
  776.  
  777.     pMinStringG::
  778. pMinStringG ()
  779.    :minStringG(TRUE), Count(0), String(0)
  780.    {ref();
  781.        {String = new char[1];
  782.     *String = '\0';
  783.        }
  784.     deref();
  785.    }
  786.  
  787.     pMinStringG::
  788. pMinStringG (const seqG* S)
  789.    :minStringG(TRUE), Count(0), String(0)
  790.    {ref();
  791.        {minStringA Temp = minStringA::make(S);
  792.         Count = Temp.count();
  793.     String = new char[Count+1];
  794.     characterA C;
  795.     char * End = String;
  796.     for(stringPosA P = Temp.makePos(); P(); ++P)
  797.         *End++ = (*P).value();
  798.     *End = '\0';
  799.        }
  800.     deref();
  801.    }
  802.  
  803.     pMinStringG::
  804. pMinStringG (const posG* Start, const posG* Beyond)
  805.    :minStringG(TRUE), Count(0), String(0)
  806.    {ref();
  807.        {minStringA Temp = minStringA::make(Start, Beyond);
  808.         Count = Temp.count();
  809.     String = new char[Count+1];
  810.     characterA C;
  811.     char * End = String;
  812.     for(stringPosA P = Temp.makePos(); P(); ++P)
  813.         *End++ = (*P).value();
  814.     *End = '\0';
  815.        }
  816.     deref();
  817.    }
  818.  
  819.     pMinStringG::
  820. pMinStringG (const char * S)        // NUL-terminated string
  821.    :minStringG(TRUE), Count(strlen(S)), String(0)
  822.    {ref();
  823.        {String = new char[Count+1];
  824.     strcpy(String, S);
  825.        }
  826.     deref();
  827.    }
  828.  
  829.     pMinStringG::
  830. pMinStringG (const char * Start, const char * Beyond)
  831.    :minStringG(TRUE), Count(Beyond - Start), String(0)
  832.    {ref();
  833.        {String = new char[Count+1];
  834.     memcpy(String, Start, Count); 
  835.     String[Count] = '\0';
  836.        }
  837.     deref();
  838.    }
  839.  
  840.     pMinStringG::
  841. pMinStringG (int Uppercase, const seqG* S)
  842.    :minStringG(TRUE), Count(S->count()), String(0)
  843.    {ref();
  844.        {minStringA Temp = minStringA::make(S);
  845.         Count = Temp.count();
  846.     String = new char[Count+1];
  847.     characterA C;
  848.     char * End = String;
  849.     for(stringPosA P = Temp.makePos(); P(); ++P)
  850.        {if(Uppercase)
  851.             *End++ = (*P).uppercase().value();
  852.         else
  853.             *End++ = (*P).lowercase().value();
  854.        }
  855.     *End = '\0';
  856.        }
  857.     deref();
  858.    }
  859.  
  860.     pMinStringG::
  861. pMinStringG (int Uppercase, const posG* Start, const posG* Beyond)
  862.    :minStringG(TRUE), Count(0), String(0)
  863.    {ref();
  864.        {minStringA Temp = minStringA::make(Start, Beyond);
  865.         Count = Temp.count();
  866.     String = new char[Count+1];
  867.     characterA C;
  868.     char * End = String;
  869.     for(stringPosA P = Temp.makePos(); P(); ++P)
  870.        {if(Uppercase)
  871.             *End++ = (*P).uppercase().value();
  872.         else
  873.             *End++ = (*P).lowercase().value();
  874.        }
  875.     *End = '\0';
  876.        }
  877.     deref();
  878.    }
  879.  
  880.     pMinStringG::
  881. pMinStringG (int Uppercase, const char * S)
  882.    :minStringG(TRUE), Count(strlen(S)), String(0)
  883.    {ref();
  884.        {String = new char[Count+1];
  885.     for(int I = 0; I < Count; I++)
  886.         String[I] = (Uppercase ? toupper(S[I]) : tolower(S[I]));
  887.        }
  888.     deref();
  889.    }
  890.  
  891.     pMinStringG::
  892. pMinStringG (int Uppercase, const char * Start, const char * Beyond)
  893.    :minStringG(TRUE), Count(Beyond - Start), String(0)
  894.    {ref();
  895.        {String = new char[Count+1];
  896.     for(int I = 0; I < Count; I++)
  897.         String[I] = (Uppercase ? toupper(Start[I]) : tolower(Start[I]));
  898.        }
  899.     deref();
  900.    }
  901.  
  902.  
  903. // oathCore Operations //////////
  904.  
  905.     void pMinStringG::
  906. export (exportP& X) const
  907.    {X.writeType(TypeName);
  908.     int Count = count();
  909.     X.stream() << Count << ' ';
  910.     if(Count)
  911.         X.stream().write(String, Count);
  912.    }
  913.  
  914.     objA pMinStringG::
  915. import (importP& M)
  916.    {int Count;
  917.     M.stream() >> Count;
  918.     M.stream().get();
  919.     if(Count)
  920.        {char* String = new char [Count];
  921.         M.stream().read(String, Count);
  922.     return new pMinStringG (String);
  923.        }
  924.     else
  925.         return new pMinStringG ();
  926.    }
  927.  
  928.  
  929. // obj Operations //////////
  930.  
  931.     int pMinStringG::
  932. isEqual (const objG* O) const
  933.    {if(is(O))
  934.     return TRUE;
  935.     else if(O->isImplementedAs(Type))
  936.        {const pMinStringG* PS = (pMinStringG*)O;
  937.         return (Count == PS->Count) && !memcmp(String, PS->String, Count);
  938.        }
  939.     else if(O->isType(stringG::Type))
  940.        {const stringG* S = (stringG*)O;
  941.         posA Pthis = makePos(0, 0);
  942.     posA PS    = S->makePos(0, 0);
  943.     while(Pthis())
  944.        {if(PS.isPastEnd())
  945.             return FALSE;
  946.         if(!(*Pthis).is(*PS))
  947.             return FALSE;
  948.         ++Pthis;
  949.         ++PS;
  950.        }
  951.     return (PS.isPastEnd() ? TRUE : FALSE);
  952.        }
  953.     else
  954.         return FALSE;
  955.    }
  956.  
  957.  
  958. // bag Operations //////////
  959.  
  960.     int pMinStringG::
  961. isEmpty () const
  962.    {return !Count;}
  963.  
  964.     int pMinStringG::
  965. count () const
  966.    {return Count;}
  967.  
  968.     int pMinStringG::
  969. contains (const objG* O) const
  970.    {return O->isImplementedAs(characterG::Type) 
  971.        && (int)(memchr(String, ((characterG*)O)->value(), Count));
  972.    }
  973.  
  974.     int pMinStringG::
  975. containsEqual (const objG* O) const
  976.    {return O->isImplementedAs(characterG::Type) 
  977.        && (int)(memchr(String, ((characterG*)O)->value(), Count));
  978.    }
  979.  
  980.     int pMinStringG::
  981. canContain (const objG* O) const
  982.    {return O->isImplementedAs(characterG::Type);}
  983.  
  984.     void pMinStringG::
  985. insert (const objG*)
  986.    {ensure(FALSE, "Attempted to modify a const string!");}
  987.  
  988.     void pMinStringG::
  989. append (const bagG*)
  990.    {ensure(FALSE, "Attempted to modify a const string!");}
  991.  
  992.     void pMinStringG::
  993. apply (void (*F)(objA)) const
  994.    {for(const char *N = String; *N; N++)
  995.     F(characterA::make(*N));
  996.    }
  997.  
  998.     bagG* pMinStringG::
  999. applyX (objA (*F)(objA), bagG* B) const
  1000.    {for(const char *N = String; *N; N++)
  1001.        {objA O = F(characterA::make(*N));
  1002.         B->insert(O.guts());
  1003.        }
  1004.     return B;
  1005.    }
  1006.  
  1007.     bagG* pMinStringG::
  1008. applyX (bagA (*F)(objA), bagG* B) const
  1009.    {for(const char *N = String; *N; N++)
  1010.        {bagA O = F(characterA::make(*N));
  1011.         B->append(O.guts());
  1012.        }
  1013.     return B;
  1014.    }
  1015.  
  1016. // queue Operations //////////
  1017.  
  1018.     const objG* pMinStringG::
  1019. remove ()
  1020.    {ensure(FALSE, "Attempted to modify a const string!");
  1021.     return Nil;
  1022.    }
  1023.  
  1024.  
  1025. // seq Operations //////////
  1026.  
  1027.     const objG* pMinStringG::
  1028. subscript (int I) const
  1029.    {assumed(I <= Count, "Indexed beyond end of String!");
  1030.     return characterA::make(String[I]).guts();
  1031.    }
  1032.  
  1033.     const objG* pMinStringG::
  1034. subscript (const posG* P) const
  1035.    {ensure(is(P->parent()), "Position not from this String!");
  1036.     return P->indirection();
  1037.    }
  1038.  
  1039.     seqA pMinStringG::
  1040. makeSeq (const posG* Start, const posG* Beyond, int MakeConst) const
  1041.    {ensure(is(Start->parent()), "pos is not from this seq!");
  1042.     return MakeConst ? (seqG*)new pMinStringG  (Start, Beyond)
  1043.              : (seqG*)new dlMinStringG (Start, Beyond);
  1044.    }
  1045.  
  1046.     seqA pMinStringG::
  1047. makeSeq (int Start, int Beyond, int MakeConst) const
  1048.    {ensure(Start <= Count, "Start is out of range!");
  1049.     return MakeConst ? (seqG*)new pMinStringG  (internalPosition(Start),
  1050.                             internalPosition(Beyond))
  1051.              : (seqG*)new dlMinStringG (internalPosition(Start),
  1052.                             internalPosition(Beyond));
  1053.    }
  1054.  
  1055.  
  1056. // fifoQueue Operations //////////
  1057.  
  1058. // deq Operations //////////
  1059.  
  1060.     void pMinStringG::
  1061. pushFront (const objG*)
  1062.    {ensure(FALSE, "Attempted to modify a const string!");}
  1063.  
  1064.     const objG* pMinStringG::
  1065. pullEnd ()
  1066.    {ensure(FALSE, "Attempted to modify a const string!");
  1067.     return Nil;
  1068.    }
  1069.  
  1070.  
  1071. // list Operations //////////
  1072.  
  1073.     void pMinStringG::
  1074. insertList (const listPosG*, const objG*)
  1075.    {ensure(FALSE, "Attempted to modify a const string!");}
  1076.  
  1077.     const objG* pMinStringG::
  1078. removeList (const listPosG*)
  1079.    {ensure(FALSE, "Attempted to modify a const string!");
  1080.     return Nil;
  1081.    }
  1082.  
  1083.  
  1084. // string Operations //////////
  1085.  
  1086.     const char * pMinStringG::
  1087. charStar () const
  1088.    {char * RV = new char [Count + 1];
  1089.     memcpy(RV, String, Count+1);
  1090.     return RV;
  1091.    }
  1092.  
  1093.     void pMinStringG::
  1094. charStarX (char * C, int N) const
  1095.    {memcpy(C, String, (N <= Count ? N : Count+1));}
  1096.  
  1097.     int pMinStringG::
  1098. hash () const    // K = 4
  1099.    {int H = 0;
  1100.     for(int I = 0; I < Count; I++)
  1101.     H = (H << 2) + String[I];
  1102.     return abs(H);
  1103.    }
  1104.  
  1105.     int pMinStringG::
  1106. hash (int K) const
  1107.    {if(K == 4)
  1108.         return pMinStringG::hash();
  1109.     else
  1110.        {int H = 0;
  1111.         for(int I = 0; I < Count; I++)
  1112.         H = (K * H) + String[I];
  1113.     return abs(H);
  1114.        }
  1115.    }
  1116.  
  1117.     int pMinStringG::
  1118. hashLower () const    // K = 4
  1119.    {int H = 0;
  1120.     for(int I = 0; I < Count; I++)
  1121.     H = (H << 2) + tolower(String[I]);
  1122.     return abs(H);
  1123.    }
  1124.  
  1125.     int pMinStringG::
  1126. hashLower (int K) const
  1127.    {if(K == 4)
  1128.         return pMinStringG::hashLower();
  1129.     else
  1130.        {int H = 0;
  1131.         for(int I = 0; I < Count; I++)
  1132.         H = (K * H) + tolower(String[I]);
  1133.     return abs(H);
  1134.        }
  1135.    }
  1136.  
  1137.     int pMinStringG::
  1138. hashUpper () const    // K = 4
  1139.    {int H = 0;
  1140.     for(int I = 0; I < Count; I++)
  1141.     H = (H << 2) + toupper(String[I]);
  1142.     return abs(H);
  1143.    }
  1144.  
  1145.     int pMinStringG::
  1146. hashUpper (int K) const
  1147.    {if(K == 4)
  1148.         return pMinStringG::hashUpper();
  1149.     else
  1150.        {int H = 0;
  1151.         for(int I = 0; I < Count; I++)
  1152.         H = (K * H) + toupper(String[I]);
  1153.     return abs(H);
  1154.        }
  1155.    }
  1156.  
  1157.     int pMinStringG::
  1158. isEqual (const char * C) const
  1159.    {return (Count == strlen(C)) && !memcmp(String, C, Count);}
  1160.  
  1161.     int pMinStringG::
  1162. isEqual (const stringPosG* Start, const stringPosG* Beyond) const
  1163.    {posA Pthis = makePos(0, 0);
  1164.     posA PS    = (posA&)Start->makeCopy(0);
  1165.     while(Pthis())
  1166.        {if(Beyond->isEqual(PS.guts()))
  1167.         return FALSE;
  1168.     if(*Pthis != *PS)
  1169.         return FALSE;
  1170.     ++Pthis;
  1171.     ++PS;
  1172.        }
  1173.     return (Beyond->isEqual(PS.guts()) ? TRUE : FALSE);
  1174.    }
  1175.  
  1176.     int pMinStringG::
  1177. isEqualAnyCase (const stringG* S) const
  1178.    {stringPosA Pthis = (stringPosA&)makePos(0, 0);
  1179.     stringPosA PS    = (stringPosA&)S->makePos(0, 0);
  1180.     while(Pthis())
  1181.        {if(PS.isPastEnd())
  1182.         return FALSE;
  1183.     if((*Pthis).lowercase() != (*PS).lowercase())
  1184.         return FALSE;
  1185.     ++Pthis;
  1186.     ++PS;
  1187.        }
  1188.     return (PS.isPastEnd() ? TRUE : FALSE);
  1189.    }
  1190.  
  1191.     int pMinStringG::
  1192. isEqualAnyCase (const char * PS) const    // can be faster
  1193.    {stringPosA Pthis = (stringPosA&)makePos(0, 0);
  1194.     while(Pthis())
  1195.        {if(!*PS)
  1196.         return FALSE;
  1197.     if(((*Pthis).lowercase().value() != tolower(*PS)))
  1198.         return FALSE;
  1199.     ++Pthis;
  1200.     ++PS;
  1201.        }
  1202.     return (!*PS ? TRUE : FALSE);
  1203.    }
  1204.  
  1205.     int pMinStringG::
  1206. isEqualAnyCase (const stringPosG* Start, const stringPosG* Beyond) const
  1207.    {stringPosA Pthis = (stringPosA&)makePos(0, 0);
  1208.     stringPosA PS    = (stringPosA&)Start->makeCopy(0);
  1209.     stringPosA PE    = Beyond;
  1210.     while(Pthis())
  1211.        {if(PE == PS)
  1212.         return FALSE;
  1213.     if(((*Pthis).lowercase() != (*PS).lowercase()))
  1214.         return FALSE;
  1215.     ++Pthis;
  1216.     ++PS;
  1217.        }
  1218.     return (PE == PS ? TRUE : FALSE);
  1219.    }
  1220.  
  1221.     int pMinStringG::
  1222. lessThan (const stringG* S) const
  1223.    {if(is(S))
  1224.     return FALSE;
  1225.     if(S->isImplementedAs(Type))
  1226.     return memcmp(String, ((pMinStringG*)S)->String, Count) < 0;
  1227.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  1228.     stringPosA PS    = (stringPosA&)S->makePos(0, 0);
  1229.     while(Pthis())
  1230.        {if(PS.isPastEnd())
  1231.         return FALSE;
  1232.     characterA Cthis = *Pthis;
  1233.     characterA CS    = *PS;
  1234.     if(Cthis < CS)
  1235.         return TRUE;
  1236.     if(Cthis > CS)
  1237.         return FALSE;
  1238.     ++Pthis;
  1239.     ++PS;
  1240.        }
  1241.     if(Pthis.isPastEnd())
  1242.     return (PS.isPastEnd() ? FALSE : TRUE);
  1243.    }
  1244.  
  1245.     int pMinStringG::
  1246. moreThan (const stringG* S) const
  1247.    {if(is(S))
  1248.     return FALSE;
  1249.     if(S->isImplementedAs(Type))
  1250.     return memcmp(String, ((pMinStringG*)S)->String, Count) > 0;
  1251.     stringPosA Pthis = (stringPosA&)makePos(0, 0);
  1252.     stringPosA PS    = (stringPosA&)S->makePos(0, 0);
  1253.     while(PS())
  1254.        {if(Pthis.isPastEnd())
  1255.         return FALSE;
  1256.     characterA Cthis = *Pthis;
  1257.     characterA CS    = *PS;
  1258.     if(Cthis > CS)
  1259.         return TRUE;
  1260.     if(Cthis < CS)
  1261.         return FALSE;
  1262.     ++Pthis;
  1263.     ++PS;
  1264.        }
  1265.     if(PS.isPastEnd())
  1266.     return (Pthis.isPastEnd() ? FALSE : TRUE);
  1267.    }
  1268.  
  1269.     ostream& pMinStringG::
  1270. ostreamInsertion (ostream& F) const
  1271.    {return F.write(String, Count);}
  1272.  
  1273.     istream& pMinStringG::
  1274. istreamExtraction (istream& F)
  1275.    {ensure(FALSE, "Attempted to modify a const string!");
  1276.     return F;
  1277.    }
  1278.  
  1279.     void pMinStringG::
  1280. stringInsert (const characterG*)
  1281.    {ensure(FALSE, "Attempted to modify a const string!");}
  1282.  
  1283.     void pMinStringG::
  1284. stringInsert (char)
  1285.    {ensure(FALSE, "Attempted to modify a const string!");}
  1286.  
  1287.     void pMinStringG::
  1288. stringAppend (const stringG*)
  1289.    {ensure(FALSE, "Attempted to modify a const string!");}
  1290.  
  1291.     inline void pMinStringG::
  1292. stringAppend (const char*)
  1293.    {ensure(FALSE, "Attempted to modify a const string!");}
  1294.  
  1295.     stringG* pMinStringG::
  1296. applyStringX (characterA (*F)(characterA), stringG* S) const
  1297.    {for(const char *N = String; *N; N++)
  1298.        {characterA C = F(characterA::make(*N));
  1299.         S->stringInsert(C.guts());
  1300.        }
  1301.     return S;
  1302.    }
  1303.  
  1304.     stringG* pMinStringG::
  1305. applyStringX (stringA (*F)(characterA), stringG* S) const
  1306.    {for(const char *N = String; *N; N++)
  1307.        {stringA C = F(characterA::make(*N));
  1308.         S->stringAppend(C.guts());
  1309.        }
  1310.     return S;
  1311.    }
  1312.  
  1313.     void pMinStringG::
  1314. lowercase ()
  1315.    {ensure(FALSE, "Sorry, not implemented!");}
  1316.  
  1317.     void pMinStringG::
  1318. uppercase ()
  1319.    {ensure(FALSE, "Sorry, not implemented!");}
  1320.  
  1321.     stringA pMinStringG::
  1322. makeLower (int MakeConst) const
  1323.    {return MakeConst ? (stringG*)new pMinStringG  (FALSE, this)
  1324.              : (stringG*)new dlMinStringG (FALSE, this);
  1325.    }
  1326.  
  1327.     stringA pMinStringG::
  1328. makeUpper (int MakeConst) const
  1329.    {return MakeConst ? (stringG*)new pMinStringG  (TRUE, this)
  1330.              : (stringG*)new dlMinStringG (TRUE, this);
  1331.    }
  1332.  
  1333.  
  1334. /////////////////////////////////////////////////////////////////////////////
  1335. // minStringPos Outlines
  1336.  
  1337. OUTLINES(minStringPos, stringPos)
  1338.  
  1339.  
  1340. /////////////////////////////////////////////////////////////////////////////
  1341. // dlMinStringPosG Outlines
  1342.  
  1343. OUTLINES_G(dlMinStringPos, minStringPos)
  1344.  
  1345. // Constructors //////////
  1346.  
  1347.     dlMinStringPosG::
  1348. dlMinStringPosG (const minStringG* iString, dlcNodeP* iPrev, int IsConst)
  1349.    :minStringPosG(iString, IsConst),
  1350.     Prev(iPrev), PrevPos(0), NextPos(parentT()->posList())
  1351.    {if(NextPos)
  1352.     NextPos->PrevPos = this;
  1353.     parentT()->posList() = this;
  1354.    }
  1355.  
  1356.     dlMinStringPosG::
  1357. ~dlMinStringPosG ()
  1358.    {if(NextPos)
  1359.     NextPos->PrevPos = PrevPos;
  1360.     if(PrevPos)
  1361.     PrevPos->NextPos = NextPos;
  1362.     else
  1363.     parentT()->posList() = NextPos;
  1364.    }
  1365.  
  1366.  
  1367. // oathCore Operations //////////
  1368.  
  1369.     void dlMinStringPosG::
  1370. export (exportP& X) const
  1371.    {X.writeType(TypeName);
  1372.     String.export(X);
  1373.     int I = 0;
  1374.     minStringPosA P = String.makePos();
  1375.     while(((dlMinStringPosG*)(P.guts()))->Prev != Prev)
  1376.        {++P; ++I;}
  1377.     X.stream() << I << (isConst() ? ' ' : '\0');
  1378.    }
  1379.  
  1380.     objA dlMinStringPosG::
  1381. import (importP& M)
  1382.    {minStringA S = minStringA::isa(objA::import(M));
  1383.     int I;
  1384.     M.stream() >> I;
  1385.     char MakeConst = M.stream().get();
  1386.     return S.makePos(I, MakeConst);
  1387.    }
  1388.  
  1389.  
  1390. // obj Operations //////////
  1391.  
  1392.     int dlMinStringPosG::
  1393. isEqual (const objG* O) const
  1394.    {return O->isImplementedAs(Type) 
  1395.        && String.guts()->is(((posG*)O)->parent())
  1396.        && Prev == ((dlMinStringPosG*)O)->Prev;
  1397.    }
  1398.  
  1399.  
  1400. // pos Operations //////////
  1401.  
  1402.     const objG* dlMinStringPosG::
  1403. indirection () const
  1404.    {assumed(Prev->next(), "Access attempted past end of Sequence");
  1405.     return Prev->nextObj().guts();
  1406.    }
  1407.  
  1408.     void dlMinStringPosG::
  1409. increment ()
  1410.    {NOT_CONST();
  1411.     if(Prev->next())
  1412.      Prev = Prev->next();
  1413.    }
  1414.  
  1415.     void dlMinStringPosG::
  1416. increment (int I)
  1417.    {NOT_CONST();
  1418.     for(int J = 0; (J < I) && Prev->next(); J++)
  1419.     Prev = Prev->next();
  1420.    }
  1421.  
  1422.     const objG* dlMinStringPosG::
  1423. find (const objG* O)
  1424.    {NOT_CONST();
  1425.     dlcNodeP * P = Prev;
  1426.     dlcNodeP * N;
  1427.     while(N = P->next())
  1428.        {if(O->is(N->thisObj().guts()))
  1429.        {Prev = P;
  1430.         return O;
  1431.        }
  1432.     P = N;
  1433.        }
  1434.     return Nil;
  1435.    }
  1436.  
  1437.     const objG* dlMinStringPosG::
  1438. findEqual (const objG* O)
  1439.    {NOT_CONST();
  1440.     dlcNodeP * P = Prev;
  1441.     dlcNodeP * N;
  1442.     while(N = P->next())
  1443.        {if(O->isEqual(N->thisObj().guts()))
  1444.        {Prev = P;
  1445.         return O;
  1446.        }
  1447.     P = N;
  1448.        }
  1449.     return Nil;
  1450.    }
  1451.  
  1452.     void dlMinStringPosG::
  1453. reset (const posG* P)
  1454.    {NOT_CONST();
  1455.     ensure(String.guts()->is(P->parent()), "Pos's not from same seq!");
  1456.     Prev = ((dlMinStringPosG*)P)->Prev;
  1457.    }
  1458.  
  1459.     void dlMinStringPosG::
  1460. reset (int I)
  1461.    {NOT_CONST();
  1462.     Prev = parentT()->internalPosition(I);}
  1463.  
  1464.  
  1465. // listPos Operations //////////
  1466.  
  1467.     void dlMinStringPosG::
  1468. decrement ()
  1469.    {NOT_CONST();
  1470.     if(Prev->prev())
  1471.     Prev = Prev->prev();
  1472.    }
  1473.  
  1474.     void dlMinStringPosG::
  1475. decrement (int I)
  1476.    {NOT_CONST();
  1477.     for(int J = 0; (J < I) && Prev->prev(); J++)
  1478.     Prev = Prev->prev();
  1479.    }
  1480.  
  1481.  
  1482. // stringPos Operations //////////
  1483.  
  1484.     const characterG* dlMinStringPosG::
  1485. charIndirection () const
  1486.    {assumed(Prev->next(), "Access attempted past end of Sequence");
  1487.     return Prev->nextObj().guts();
  1488.    }
  1489.  
  1490.     int dlMinStringPosG::
  1491. skipSpaces ()
  1492.    {NOT_CONST();
  1493.     if(isPastEnd() || !isspace(charIndirection()->value()))
  1494.         return FALSE;
  1495.     do {increment();
  1496.        } while(!isPastEnd() && isspace(charIndirection()->value()));
  1497.     return TRUE;
  1498.    }
  1499.  
  1500.     const stringG* dlMinStringPosG::
  1501. match (const stringG* S)
  1502.    {NOT_CONST();
  1503.     dlcNodeP * PT  = Prev;
  1504.     posA       PS  = S->makePos(0, 0);
  1505.     //E&S//while(PS() && PT->next() && (*PS == PT->nextObj()))
  1506.     while(PS() && PT->next())
  1507.        {if(*PS != PT->nextObj())
  1508.             break;
  1509.         ++PS;
  1510.     PT = PT->next();
  1511.        }
  1512.     if(PS())
  1513.     return stringG::Nil;
  1514.     else
  1515.        {Prev = PT;
  1516.     return S;
  1517.        }
  1518.    }
  1519.  
  1520.     int dlMinStringPosG::
  1521. canMatch (const stringG* S) const
  1522.    {dlcNodeP * PT  = Prev;
  1523.     posA       PS  = S->makePos(0, 0);
  1524.     //E&S//while(PS() && PT->next() && (*PS == PT->nextObj()))
  1525.     while(PS() && PT->next())
  1526.        {if(*PS != PT->nextObj())
  1527.             break;
  1528.         ++PS;
  1529.     PT = PT->next();
  1530.        }
  1531.     return !PS();
  1532.    }
  1533.  
  1534.     const stringG* dlMinStringPosG::
  1535. findString (const stringG* S)
  1536.    {NOT_CONST();
  1537.     dlcNodeP * PTStart = Prev;
  1538.     posA       PS      = S->makePos(0, 0);
  1539.     while(PTStart->next())
  1540.        {dlcNodeP * PT = PTStart;
  1541.     PS.reset();
  1542.     //E&S//while(PS() && PT->next() && (*PS == PT->nextObj()))
  1543.     while(PS() && PT->next())
  1544.            {if(*PS != PT->nextObj())
  1545.             break;
  1546.         ++PS;
  1547.         PT = PT->next();
  1548.        }
  1549.         if(!PS())
  1550.        {Prev = PTStart;
  1551.         return S;
  1552.        }
  1553.         if(!PT->next())
  1554.         break;
  1555.     PTStart = PTStart->next();
  1556.        }
  1557.     return stringG::Nil;
  1558.    }
  1559.  
  1560.     const stringG* dlMinStringPosG::
  1561. findMatch (const stringG* S)
  1562.    {NOT_CONST();
  1563.     dlcNodeP * PTStart = Prev;
  1564.     posA       PS      = S->makePos(0, 0);
  1565.     while(PTStart->next())
  1566.        {dlcNodeP * PT = PTStart;
  1567.     PS.reset();
  1568.     //E&S//while(PS() && PT->next() && (*PS == PT->nextObj()))
  1569.     while(PS() && PT->next())
  1570.            {if(*PS != PT->nextObj())
  1571.             break;
  1572.         ++PS;
  1573.         PT = PT->next();
  1574.        }
  1575.         if(!PS())
  1576.        {Prev = PT;
  1577.         return S;
  1578.        }
  1579.         if(!PT->next())
  1580.         break;
  1581.     PTStart = PTStart->next();
  1582.        }
  1583.     return stringG::Nil;
  1584.    }
  1585.  
  1586.     const stringG* dlMinStringPosG::
  1587. matchAnyCase (const stringG* S)
  1588.    {NOT_CONST();
  1589.     stringPosA PT = (stringPosA&)makeCopy(0);
  1590.     stringPosA PS = (stringPosA&)S->makePos(0, 0);
  1591.     //E&S//while(PS() && PT() && ((*PS).lowercase() == (*PT).lowercase()))
  1592.     while(PS() && PT())
  1593.        {if((*PS).lowercase() != (*PT).lowercase())
  1594.             break;
  1595.     ++PS; 
  1596.     ++PT;
  1597.        }
  1598.     if(PS())
  1599.     return stringG::Nil;
  1600.     else
  1601.        {reset(PT.guts());
  1602.     return S;
  1603.        }
  1604.    }
  1605.  
  1606.     int dlMinStringPosG::
  1607. canMatchAnyCase (const stringG* S) const
  1608.    {stringPosA PT = (stringPosA&)makeCopy(0);
  1609.     stringPosA PS = (stringPosA&)S->makePos(0, 0);
  1610.     //E&S//while(PS() && PT() && ((*PS).lowercase() == (*PT).lowercase()))
  1611.     while(PS() && PT())
  1612.        {if((*PS).lowercase() != (*PT).lowercase())
  1613.             break;
  1614.     ++PS;
  1615.     ++PT;
  1616.        }
  1617.     return !PS();
  1618.    }
  1619.  
  1620.     const stringG* dlMinStringPosG::
  1621. findAnyCase (const stringG* S)
  1622.    {NOT_CONST();
  1623.     dlcNodeP * PTStart = Prev;
  1624.     stringPosA PS      = (stringPosA&)S->makePos(0, 0);
  1625.     while(PTStart->next())
  1626.        {dlcNodeP * PT = PTStart;
  1627.     PS.reset();
  1628.     while(PS() && PT->Next)
  1629.            {if((*PS).lowercase() != PT->nextObj().lowercase())
  1630.             break;
  1631.         ++PS;
  1632.         PT = PT->next();
  1633.        }
  1634.         if(!PS())
  1635.        {Prev = PTStart;
  1636.         return S;
  1637.        }
  1638.         if(!PT->next())
  1639.         break;
  1640.     PTStart = PTStart->next();
  1641.        }
  1642.     return stringG::Nil;
  1643.    }
  1644.  
  1645.     const stringG* dlMinStringPosG::
  1646. findMatchAnyCase (const stringG* S)
  1647.    {NOT_CONST();
  1648.     dlcNodeP * PTStart = Prev;
  1649.     stringPosA PS      = (stringPosA&)S->makePos(0, 0);
  1650.     while(PTStart->next())
  1651.        {dlcNodeP * PT = PTStart;
  1652.     PS.reset();
  1653.     while(PS() && PT->Next)
  1654.            {if((*PS).lowercase() != PT->nextObj().lowercase())
  1655.             break;
  1656.         ++PS;
  1657.         PT = PT->next();
  1658.        }
  1659.         if(!PS())
  1660.        {Prev = PT;
  1661.         return S;
  1662.        }
  1663.         if(!PT->next())
  1664.         break;
  1665.     PTStart = PTStart->next();
  1666.        }
  1667.     return stringG::Nil;
  1668.    }
  1669.  
  1670.     const char * dlMinStringPosG::
  1671. match (const char * PS)
  1672.    {NOT_CONST();
  1673.     dlcNodeP * PT = Prev;
  1674.     while(*PS && PT->next())
  1675.        {if(*PS != PT->nextObj().value())
  1676.         return 0;
  1677.     ++PS;
  1678.     PT = PT->next();
  1679.        }
  1680.     if(*PS)
  1681.     return 0;
  1682.     Prev = PT;
  1683.     return PS;
  1684.    }
  1685.  
  1686.     int dlMinStringPosG::
  1687. canMatch (const char * PS) const
  1688.    {dlcNodeP * PT = Prev;
  1689.     while(*PS && PT->next())
  1690.        {if(*PS != PT->nextObj().value())
  1691.         return FALSE;
  1692.     ++PS;
  1693.     PT = PT->next();
  1694.        }
  1695.     return !(*PS);
  1696.    }
  1697.  
  1698.     const char * dlMinStringPosG::
  1699. findString (const char * S)
  1700.    {NOT_CONST();
  1701.     dlcNodeP * PTStart = Prev;
  1702.     while(PTStart->next())
  1703.        {dlcNodeP * PT = PTStart;
  1704.         const char * PS = S;
  1705.     while(*PS && PT->next() && (*PS == PT->nextObj().value()))
  1706.            {++PS;
  1707.         PT = PT->next();
  1708.        }
  1709.         if(!*PS)
  1710.        {Prev = PTStart;
  1711.         return S;
  1712.        }
  1713.         if(!PT->next())
  1714.         return 0;
  1715.     PTStart = PTStart->next();
  1716.        }
  1717.     return 0;
  1718.    }
  1719.  
  1720.     const char * dlMinStringPosG::
  1721. findMatch (const char * S)
  1722.    {NOT_CONST();
  1723.     dlcNodeP * PTStart = Prev;
  1724.     while(PTStart->next())
  1725.        {dlcNodeP * PT = PTStart;
  1726.         const char * PS = S;
  1727.     while(*PS && PT->next() && (*PS == PT->nextObj().value()))
  1728.            {++PS;
  1729.         PT = PT->next();
  1730.        }
  1731.         if(!*PS)
  1732.        {Prev = PT;
  1733.         return S;
  1734.        }
  1735.         if(!PT->next())
  1736.         return 0;
  1737.     PTStart = PTStart->next();
  1738.        }
  1739.     return 0;
  1740.    }
  1741.  
  1742.     const char * dlMinStringPosG::
  1743. matchAnyCase (const char *PS)
  1744.    {NOT_CONST();
  1745.     dlcNodeP * PT = Prev;
  1746.     while(*PS && PT->next())
  1747.        {if(tolower(*PS) != tolower(PT->nextObj().value()))
  1748.         return 0;
  1749.     ++PS;
  1750.     PT = PT->next();
  1751.        }
  1752.     if(*PS)
  1753.     return 0;
  1754.     Prev = PT;
  1755.     return PS;
  1756.    }
  1757.  
  1758.     int dlMinStringPosG::
  1759. canMatchAnyCase (const char *PS) const
  1760.    {dlcNodeP * PT = Prev;
  1761.     while(*PS && PT->next())
  1762.        {if(tolower(*PS) != tolower(PT->nextObj().value()))
  1763.         return FALSE;
  1764.     ++PS;
  1765.     PT = PT->next();
  1766.        }
  1767.     return !(*PS);
  1768.    }
  1769.  
  1770.     const char * dlMinStringPosG::
  1771. findAnyCase (const char * S)
  1772.    {NOT_CONST();
  1773.     dlcNodeP *  PTStart = Prev;
  1774.     while(PTStart->next())
  1775.        {dlcNodeP * PT = PTStart;
  1776.         const char * PS = S;
  1777.     while(*PS && PT->next() 
  1778.               && (tolower(*PS) == tolower(PT->nextObj().value())))
  1779.            {++PS;
  1780.         PT = PT->next();
  1781.        }
  1782.         if(!*PS)
  1783.        {Prev = PTStart;
  1784.         return S;
  1785.        }
  1786.         if(!PT->next())
  1787.         return 0;
  1788.     PTStart = PTStart->next();
  1789.        }
  1790.     return 0;
  1791.    }
  1792.  
  1793.     const char * dlMinStringPosG::
  1794. findMatchAnyCase (const char * S)
  1795.    {NOT_CONST();
  1796.     dlcNodeP *  PTStart = Prev;
  1797.     while(PTStart->next())
  1798.        {dlcNodeP * PT = PTStart;
  1799.         const char * PS = S;
  1800.     while(*PS && PT->next() 
  1801.               && (tolower(*PS) == tolower(PT->nextObj().value())))
  1802.            {++PS;
  1803.         PT = PT->next();
  1804.        }
  1805.         if(!*PS)
  1806.        {Prev = PT;
  1807.         return S;
  1808.        }
  1809.         if(!PT->next())
  1810.         return 0;
  1811.     PTStart = PTStart->next();
  1812.        }
  1813.     return 0;
  1814.    }
  1815.  
  1816. /////////////////////////////////////////////////////////////////////////////
  1817. // pMinStringPosG Outlines
  1818.  
  1819. OUTLINES_G(pMinStringPos, minStringPos)
  1820.  
  1821. // oathCore Operations //////////
  1822.  
  1823.     void pMinStringPosG::
  1824. export (exportP& X) const
  1825.    {X.writeType(TypeName);
  1826.     String.export(X);
  1827.     int I = 0;
  1828.     minStringPosA P = String.makePos();
  1829.     while(((pMinStringPosG*)(P.guts()))->Char != Char)
  1830.        {++P; ++I;}
  1831.     X.stream() << I << (isConst() ? ' ' : '\0');
  1832.    }
  1833.  
  1834.     objA pMinStringPosG::
  1835. import (importP& M)
  1836.    {minStringA S = minStringA::isa(objA::import(M));
  1837.     int I;
  1838.     M.stream() >> I;
  1839.     char MakeConst = M.stream().get();
  1840.     return S.makePos(I, MakeConst);
  1841.    }
  1842.  
  1843.  
  1844. // obj Operations //////////
  1845.  
  1846.     int pMinStringPosG::
  1847. isEqual (const objG* O) const
  1848.    {return O->isImplementedAs(Type) && Char == ((pMinStringPosG*)O)->Char;}
  1849.  
  1850. // pos Operations //////////
  1851.  
  1852.     const objG* pMinStringPosG::
  1853. indirection () const
  1854.    {ensure(!isPastEnd(), "Attempt to dereference past end of String!");
  1855.     return characterA::make(*Char).guts();
  1856.    }
  1857.  
  1858.     void pMinStringPosG::
  1859. increment ()
  1860.    {NOT_CONST();
  1861.     if(Char < parentT()->internalPastEnd())
  1862.     Char++;
  1863.    }
  1864.  
  1865.     void pMinStringPosG::
  1866. increment (int I)
  1867.    {NOT_CONST();
  1868.     Char += I;
  1869.     if(Char > parentT()->internalPastEnd())
  1870.     Char = parentT()->internalPastEnd();
  1871.    }
  1872.  
  1873.     const objG* pMinStringPosG::
  1874. find (const objG* O)
  1875.    {NOT_CONST();
  1876.     if(!O->isImplementedAs(characterG::Type))
  1877.     return Nil;
  1878.     const char * P  = Char;
  1879.     const char * PE = parentT()->internalPastEnd();
  1880.     while(P != PE)
  1881.        {if(*P == ((characterG*)O)->value())
  1882.        {Char = P;
  1883.         return O;
  1884.        }
  1885.     P++;
  1886.        }
  1887.     return objG::Nil;
  1888.    }
  1889.  
  1890.     const objG* pMinStringPosG::
  1891. findEqual (const objG* O)
  1892.    {NOT_CONST();
  1893.     if(!O->isImplementedAs(characterG::Type))
  1894.     return Nil;
  1895.     const char * P  = Char;
  1896.     const char * PE = parentT()->internalPastEnd();
  1897.     while(P != PE)
  1898.        {if(*P == ((characterG*)O)->value())
  1899.        {Char = P;
  1900.         return O;
  1901.        }
  1902.     P++;
  1903.        }
  1904.     return objG::Nil;
  1905.    }
  1906.  
  1907.     void pMinStringPosG::
  1908. reset (const posG* P)
  1909.    {NOT_CONST();
  1910.     ensure(parentT()->is(P->parent()), "Pos's are not from the same seq!");
  1911.     Char = ((const pMinStringPosG*)P)->Char;
  1912.    }
  1913.  
  1914.     void pMinStringPosG::
  1915. reset (int I)
  1916.    {NOT_CONST();
  1917.     Char = parentT()->internalPosition(I);}
  1918.  
  1919.  
  1920. // listPos Operations //////////
  1921.  
  1922.     void pMinStringPosG::
  1923. decrement ()
  1924.    {NOT_CONST();
  1925.     if(Char > parentT()->internalPosition(0))
  1926.     Char--;
  1927.    }
  1928.  
  1929.     void pMinStringPosG::
  1930. decrement (int I)
  1931.    {NOT_CONST();
  1932.     Char -= I;
  1933.     if(Char < parentT()->internalPosition(0))
  1934.     Char = parentT()->internalPosition(0);
  1935.    }
  1936.  
  1937.  
  1938. // stringPos Operations //////////
  1939.  
  1940.     const characterG* pMinStringPosG::
  1941. charIndirection () const
  1942.    {ensure(!isPastEnd(), "Attempt to dereference past end of String!");
  1943.     return characterA::make(*Char).guts();
  1944.    }
  1945.  
  1946.     int pMinStringPosG::
  1947. skipSpaces ()
  1948.    {NOT_CONST();
  1949.     if(isPastEnd() || !isspace(*Char))
  1950.         return FALSE;
  1951.     do
  1952.        {Char++;}
  1953.     while(!isPastEnd() && isspace(*Char));
  1954.     return TRUE;
  1955.    }
  1956.  
  1957.     const stringG* pMinStringPosG::
  1958. match (const stringG* S)
  1959.    {NOT_CONST();
  1960.     const char * PT   = Char;
  1961.     const char * PTPE = parentT()->internalPastEnd();
  1962.     stringPosA   PS   = (stringPosA&)S->makePos(0, 0);
  1963.     //E&S//while(PS() && (PT != PTPE) && (*PT == (*PS).value()))
  1964.     while(PS() && (PT != PTPE))
  1965.        {if(*PT != (*PS).value())
  1966.             break;
  1967.     ++PS;
  1968.     ++PT;
  1969.        }
  1970.     if(PS())
  1971.     return stringG::Nil;
  1972.     else
  1973.        {Char = PT;
  1974.     return S;
  1975.        }
  1976.    }
  1977.  
  1978.     int pMinStringPosG::
  1979. canMatch (const stringG* S) const
  1980.    {const char * PT   = Char;
  1981.     const char * PTPE = parentT()->internalPastEnd();
  1982.     stringPosA   PS   = (stringPosA&)S->makePos(0, 0);
  1983.     //E&S//while(PS() && (PT != PTPE) && (*PT == (*PS).value()))
  1984.     while(PS() && (PT != PTPE))
  1985.        {if(*PT != (*PS).value())
  1986.             break;
  1987.     ++PS;
  1988.     ++PT;
  1989.        }
  1990.     return !PS();
  1991.    }
  1992.  
  1993.     const stringG* pMinStringPosG::
  1994. findString (const stringG* S)
  1995.    {NOT_CONST();
  1996.     const char * PTStart = Char;
  1997.     const char * PTPE    = parentT()->internalPastEnd();
  1998.     stringPosA   PS      = (stringPosA&)S->makePos(0, 0);
  1999.     while(PTStart != PTPE)
  2000.        {const char * PT  = PTStart;
  2001.     PS.reset();
  2002.     //E&S//while(PS() && (PT != PTPE) && (*PT == (*PS).value()))
  2003.     while(PS() && (PT != PTPE))
  2004.            {if(*PT != (*PS).value())
  2005.             break;
  2006.         ++PS;
  2007.         ++PT;
  2008.        }
  2009.         if(!PS())
  2010.        {Char = PTStart;
  2011.         return S;
  2012.        }
  2013.         if(PT == PTPE)
  2014.         break;
  2015.     ++PTStart;
  2016.        }
  2017.     return stringG::Nil;
  2018.    }
  2019.  
  2020.     const stringG* pMinStringPosG::
  2021. findMatch (const stringG* S)
  2022.    {NOT_CONST();
  2023.     const char * PTStart = Char;
  2024.     const char * PTPE    = parentT()->internalPastEnd();
  2025.     stringPosA   PS      = (stringPosA&)S->makePos(0, 0);
  2026.     while(PTStart != PTPE)
  2027.        {const char * PT  = PTStart;
  2028.     PS.reset();
  2029.     //E&S//while(PS() && (PT != PTPE) && (*PT == (*PS).value()))
  2030.     while(PS() && (PT != PTPE))
  2031.            {if(*PT != (*PS).value())
  2032.             break;
  2033.         ++PS;
  2034.         ++PT;
  2035.        }
  2036.         if(!PS())
  2037.        {Char = PT;
  2038.         return S;
  2039.        }
  2040.         if(PT == PTPE)
  2041.         break;
  2042.     ++PTStart;
  2043.        }
  2044.     return stringG::Nil;
  2045.    }
  2046.  
  2047.     const stringG* pMinStringPosG::
  2048. matchAnyCase (const stringG* S)
  2049.    {NOT_CONST();
  2050.     const char * PT   = Char;
  2051.     const char * PTPE = parentT()->internalPastEnd();
  2052.     stringPosA   PS   = (stringPosA&)S->makePos(0, 0);
  2053.     //E&S//while(PS() && (PT != PTPE) && ((*PS).lowercase().value() == tolower(*PT)))
  2054.     while(PS() && (PT != PTPE))
  2055.        {if((*PS).lowercase().value() != tolower(*PT))
  2056.             break;
  2057.         ++PS;
  2058.         ++PT;
  2059.        }
  2060.     if(PS())
  2061.     return stringG::Nil;
  2062.     else
  2063.        {Char = PT;
  2064.     return S;
  2065.        }
  2066.    }
  2067.  
  2068.     int pMinStringPosG::
  2069. canMatchAnyCase (const stringG* S) const
  2070.    {const char * PT   = Char;
  2071.     const char * PTPE = parentT()->internalPastEnd();
  2072.     stringPosA   PS   = (stringPosA&)S->makePos(0, 0);
  2073.     //E&S//while(PS() && (PT != PTPE) && ((*PS).lowercase().value() == tolower(*PT)))
  2074.     while(PS() && (PT != PTPE))
  2075.        {if((*PS).lowercase().value() != tolower(*PT))
  2076.             break;
  2077.         ++PS;
  2078.     ++PT;
  2079.        }
  2080.     return !PS();
  2081.    }
  2082.  
  2083.     const stringG* pMinStringPosG::
  2084. findAnyCase (const stringG* S)
  2085.    {NOT_CONST();
  2086.     const char * PTStart = Char;
  2087.     const char * PTPE    = parentT()->internalPastEnd();
  2088.     stringPosA   PS      = (stringPosA&)S->makePos(0, 0);
  2089.     while(PTStart != PTPE)
  2090.        {const char * PT  = PTStart;
  2091.     PS.reset();
  2092.     //E&S//while(PS() && (PT != PTPE) 
  2093.     //E&S//       && ((*PS).lowercase().value() != tolower(*PT)))
  2094.     while(PS() && (PT != PTPE))
  2095.        {if((*PS).lowercase().value() == tolower(*PT))
  2096.             break;
  2097.         ++PS;
  2098.         ++PT;
  2099.        }
  2100.         if(!PS())
  2101.        {Char = PTStart;
  2102.         return S;
  2103.        }
  2104.         if(PT == PTPE)
  2105.         break;
  2106.     ++PTStart;
  2107.        }
  2108.     return stringG::Nil;
  2109.    }
  2110.  
  2111.     const stringG* pMinStringPosG::
  2112. findMatchAnyCase (const stringG* S)
  2113.    {NOT_CONST();
  2114.     const char * PTStart = Char;
  2115.     const char * PTPE    = parentT()->internalPastEnd();
  2116.     stringPosA   PS      = (stringPosA&)S->makePos(0, 0);
  2117.     while(PTStart != PTPE)
  2118.        {const char * PT  = PTStart;
  2119.     PS.reset();
  2120.     //E&S//while(PS() && (PT != PTPE)
  2121.     //E&S//       && ((*PS).lowercase().value() != tolower(*PT)))
  2122.     while(PS() && (PT != PTPE))
  2123.        {if((*PS).lowercase().value() == tolower(*PT))
  2124.             break;
  2125.         ++PS;
  2126.         ++PT;
  2127.        }
  2128.         if(!PS())
  2129.        {Char = PT;
  2130.         return S;
  2131.        }
  2132.         if(PT == PTPE)
  2133.         break;
  2134.     ++PTStart;
  2135.        }
  2136.     return stringG::Nil;
  2137.    }
  2138.  
  2139.     const char * pMinStringPosG::
  2140. match (const char * PS)
  2141.    {NOT_CONST();
  2142.     const char *  PT   = Char;
  2143.     const char *  PTPE = parentT()->internalPastEnd();
  2144.     while(*PS && (PT != PTPE))
  2145.        {if(*PS != *PT)
  2146.         return 0;
  2147.     ++PS; ++PT;
  2148.        }
  2149.     if(*PS)
  2150.     return 0;
  2151.     Char = PT;
  2152.     return PS;
  2153.    }
  2154.  
  2155.     int pMinStringPosG::
  2156. canMatch (const char * PS) const
  2157.    {const char *  PT   = Char;
  2158.     const char *  PTPE = parentT()->internalPastEnd();
  2159.     while(*PS && (PT != PTPE))
  2160.        {if(*PS != *PT)
  2161.         return FALSE;
  2162.     ++PS; ++PT;
  2163.        }
  2164.     return !(*PS);
  2165.    }
  2166.  
  2167.     const char * pMinStringPosG::
  2168. findString (const char * S)
  2169.    {NOT_CONST();
  2170.     const char *  PTStart = Char;
  2171.     const char *  PTPE    = parentT()->internalPastEnd();
  2172.     while(PTStart != PTPE)
  2173.        {const char * PT = PTStart;
  2174.         const char * PS = S;
  2175.     while(*PS && (PT != PTPE) && (*PS == *PT))
  2176.            {++PS; ++PT;}
  2177.         if(!*PS)
  2178.        {Char = PTStart;
  2179.         return S;
  2180.        }
  2181.         if(PT == PTPE)
  2182.         return 0;
  2183.     ++PTStart;
  2184.        }
  2185.     return 0;
  2186.    }
  2187.  
  2188.     const char * pMinStringPosG::
  2189. findMatch (const char * S)
  2190.    {NOT_CONST();
  2191.     const char *  PTStart = Char;
  2192.     const char *  PTPE    = parentT()->internalPastEnd();
  2193.     while(PTStart != PTPE)
  2194.        {const char * PT = PTStart;
  2195.         const char * PS = S;
  2196.     while(*PS && (PT != PTPE) && (*PS == *PT))
  2197.            {++PS; ++PT;}
  2198.         if(!*PS)
  2199.        {Char = PT;
  2200.         return S;
  2201.        }
  2202.         if(PT == PTPE)
  2203.         return 0;
  2204.     ++PTStart;
  2205.        }
  2206.     return 0;
  2207.    }
  2208.  
  2209.     const char * pMinStringPosG::
  2210. matchAnyCase (const char *PS)
  2211.    {NOT_CONST();
  2212.     const char *  PT   = Char;
  2213.     const char *  PTPE = parentT()->internalPastEnd();
  2214.     while(*PS && (PT != PTPE))
  2215.        {if(tolower(*PS) != tolower(*PT))
  2216.         return 0;
  2217.     ++PS; ++PT;
  2218.        }
  2219.     if(*PS)
  2220.     return 0;
  2221.     Char = PT;
  2222.     return PS;
  2223.    }
  2224.  
  2225.     int pMinStringPosG::
  2226. canMatchAnyCase (const char *PS) const
  2227.    {const char *  PT   = Char;
  2228.     const char *  PTPE = parentT()->internalPastEnd();
  2229.     while(*PS && (PT != PTPE))
  2230.        {if(tolower(*PS) != tolower(*PT))
  2231.         return FALSE;
  2232.     ++PS; ++PT;
  2233.        }
  2234.     return !(*PS);
  2235.    }
  2236.  
  2237.     const char * pMinStringPosG::
  2238. findAnyCase (const char * S)
  2239.    {NOT_CONST();
  2240.     const char *  PTStart = Char;
  2241.     const char *  PTPE    = parentT()->internalPastEnd();
  2242.     while(PTStart != PTPE)
  2243.        {const char * PT = PTStart;
  2244.         const char * PS = S;
  2245.     while(*PS && (PT != PTPE) && (tolower(*PS) == tolower(*PT)))
  2246.            {++PS; ++PT;}
  2247.         if(!*PS)
  2248.        {Char = PTStart;
  2249.         return S;
  2250.        }
  2251.         if(PT == PTPE)
  2252.         return 0;
  2253.     ++PTStart;
  2254.        }
  2255.     return 0;
  2256.    }
  2257.  
  2258.     const char * pMinStringPosG::
  2259. findMatchAnyCase (const char * S)
  2260.    {NOT_CONST();
  2261.     const char *  PTStart = Char;
  2262.     const char *  PTPE    = parentT()->internalPastEnd();
  2263.     while(PTStart != PTPE)
  2264.        {const char * PT = PTStart;
  2265.         const char * PS = S;
  2266.     while(*PS && (PT != PTPE) && (tolower(*PS) == tolower(*PT)))
  2267.            {++PS; ++PT;}
  2268.         if(!*PS)
  2269.        {Char = PT;
  2270.         return S;
  2271.        }
  2272.         if(PT == PTPE)
  2273.         return 0;
  2274.     ++PTStart;
  2275.        }
  2276.     return 0;
  2277.    }
  2278.  
  2279.  
  2280. //***************************************************************************
  2281.